{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "83e1412e",
   "metadata": {},
   "source": [
    "# FAQs\n",
    "\n",
    "### How to..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d72c8836",
   "metadata": {},
   "source": [
    "### ... get your version of PyBroker?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "cf5cff39",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1.1.27'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pybroker\n",
    "\n",
    "pybroker.__version__"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7800b3e",
   "metadata": {},
   "source": [
    "### ... get data for another symbol?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ff4e8ae5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-01-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  2 of 2 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Computing indicators...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (2 of 2) |##########################| Elapsed Time: 0:00:01 Time:  0:00:01\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Test split: 2022-01-03 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (251 of 251) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:02\n"
     ]
    }
   ],
   "source": [
    "from pybroker import ExecContext, Strategy, YFinance, highest\n",
    "\n",
    "def exec_fn(ctx: ExecContext):\n",
    "    if ctx.symbol == 'NVDA':\n",
    "        other_bar_data = ctx.foreign('AMD')\n",
    "        other_highest = ctx.indicator('high_10d', 'AMD')\n",
    "        \n",
    "strategy = Strategy(YFinance(), start_date='1/1/2022', end_date='1/1/2023')\n",
    "strategy.add_execution(\n",
    "   exec_fn, ['NVDA', 'AMD'], indicators=highest('high_10d', 'close', period=10))\n",
    "result = strategy.backtest()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b9626cfd",
   "metadata": {},
   "source": [
    "You can also retrieve models, predictions, and other data for other symbols. [For more information, refer to the ExecContext reference documentation.](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd5cfe6a",
   "metadata": {},
   "source": [
    "### ... set a limit price?\n",
    "\n",
    "Set [buy_limit_price](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext.buy_limit_price) or [sell_limit_price](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext.sell_limit_price):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e3a086d1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-03-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  1 of 1 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2022-03-01 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (212 of 212) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>symbol</th>\n",
       "      <th>date</th>\n",
       "      <th>shares</th>\n",
       "      <th>limit_price</th>\n",
       "      <th>fill_price</th>\n",
       "      <th>fees</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-04</td>\n",
       "      <td>100</td>\n",
       "      <td>431.35</td>\n",
       "      <td>430.62</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-18</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>441.04</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-06</td>\n",
       "      <td>100</td>\n",
       "      <td>446.52</td>\n",
       "      <td>446.20</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-21</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>443.56</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-22</td>\n",
       "      <td>100</td>\n",
       "      <td>433.68</td>\n",
       "      <td>431.76</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-05-06</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>410.26</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-05-09</td>\n",
       "      <td>100</td>\n",
       "      <td>407.23</td>\n",
       "      <td>401.46</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-05-23</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>394.06</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-05-24</td>\n",
       "      <td>100</td>\n",
       "      <td>392.95</td>\n",
       "      <td>391.05</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-06-08</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>413.10</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    type symbol       date  shares  limit_price  fill_price  fees\n",
       "id                                                               \n",
       "1    buy    SPY 2022-03-04     100       431.35      430.62   0.0\n",
       "2   sell    SPY 2022-03-18     100          NaN      441.04   0.0\n",
       "3    buy    SPY 2022-04-06     100       446.52      446.20   0.0\n",
       "4   sell    SPY 2022-04-21     100          NaN      443.56   0.0\n",
       "5    buy    SPY 2022-04-22     100       433.68      431.76   0.0\n",
       "6   sell    SPY 2022-05-06     100          NaN      410.26   0.0\n",
       "7    buy    SPY 2022-05-09     100       407.23      401.46   0.0\n",
       "8   sell    SPY 2022-05-23     100          NaN      394.06   0.0\n",
       "9    buy    SPY 2022-05-24     100       392.95      391.05   0.0\n",
       "10  sell    SPY 2022-06-08     100          NaN      413.10   0.0"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pybroker import ExecContext, Strategy, YFinance\n",
    "\n",
    "def buy_fn(ctx: ExecContext):\n",
    "    if not ctx.long_pos():\n",
    "        ctx.buy_shares = 100\n",
    "        ctx.buy_limit_price = ctx.close[-1] * 0.99\n",
    "        ctx.hold_bars = 10\n",
    "        \n",
    "strategy = Strategy(YFinance(), start_date='3/1/2022', end_date='1/1/2023')\n",
    "strategy.add_execution(buy_fn, 'SPY')\n",
    "result = strategy.backtest()\n",
    "result.orders.head(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "813e8b3c",
   "metadata": {},
   "source": [
    "### ... set the fill price?\n",
    "\n",
    "Set [buy_fill_price](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext.buy_fill_price) and [sell_fill_price](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext.sell_fill_price). See [PriceType](https://www.pybroker.com/en/latest/reference/pybroker.common.html#pybroker.common.PriceType) for options."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "8e9d6844",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-03-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  1 of 1 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2022-03-01 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (212 of 212) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>symbol</th>\n",
       "      <th>date</th>\n",
       "      <th>shares</th>\n",
       "      <th>limit_price</th>\n",
       "      <th>fill_price</th>\n",
       "      <th>fees</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-04</td>\n",
       "      <td>100</td>\n",
       "      <td>431.35</td>\n",
       "      <td>430.62</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-18</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>441.04</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-06</td>\n",
       "      <td>100</td>\n",
       "      <td>446.52</td>\n",
       "      <td>446.20</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-21</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>443.56</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-22</td>\n",
       "      <td>100</td>\n",
       "      <td>433.68</td>\n",
       "      <td>431.76</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-05-06</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>410.26</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-05-09</td>\n",
       "      <td>100</td>\n",
       "      <td>407.23</td>\n",
       "      <td>401.46</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-05-23</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>394.06</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-05-24</td>\n",
       "      <td>100</td>\n",
       "      <td>392.95</td>\n",
       "      <td>391.05</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-06-08</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>413.10</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    type symbol       date  shares  limit_price  fill_price  fees\n",
       "id                                                               \n",
       "1    buy    SPY 2022-03-04     100       431.35      430.62   0.0\n",
       "2   sell    SPY 2022-03-18     100          NaN      441.04   0.0\n",
       "3    buy    SPY 2022-04-06     100       446.52      446.20   0.0\n",
       "4   sell    SPY 2022-04-21     100          NaN      443.56   0.0\n",
       "5    buy    SPY 2022-04-22     100       433.68      431.76   0.0\n",
       "6   sell    SPY 2022-05-06     100          NaN      410.26   0.0\n",
       "7    buy    SPY 2022-05-09     100       407.23      401.46   0.0\n",
       "8   sell    SPY 2022-05-23     100          NaN      394.06   0.0\n",
       "9    buy    SPY 2022-05-24     100       392.95      391.05   0.0\n",
       "10  sell    SPY 2022-06-08     100          NaN      413.10   0.0"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pybroker import ExecContext, PriceType, Strategy, YFinance\n",
    "\n",
    "def exec_fn(ctx: ExecContext):\n",
    "    if ctx.long_pos():\n",
    "        ctx.buy_shares = 100\n",
    "        ctx.buy_fill_price = PriceType.AVERAGE\n",
    "    else:\n",
    "        ctx.sell_shares = 100\n",
    "        ctx.sell_fill_price = PriceType.CLOSE\n",
    "        \n",
    "strategy = Strategy(YFinance(), start_date='3/1/2022', end_date='1/1/2023')\n",
    "strategy.add_execution(buy_fn, 'SPY')\n",
    "result = strategy.backtest()\n",
    "result.orders.head(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "46d02d45",
   "metadata": {},
   "source": [
    "### ... get current positions?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "23aea40b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-03-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  2 of 2 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2022-03-01 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (212 of 212) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    }
   ],
   "source": [
    "from pybroker import ExecContext, Strategy, YFinance\n",
    "\n",
    "def exec_fn(ctx: ExecContext):\n",
    "    # Get all positions.\n",
    "    all_positions = tuple(ctx.positions())\n",
    "    # Get all long positions.\n",
    "    long_positions = tuple(ctx.long_positions())\n",
    "    # Get all short positions.\n",
    "    short_positions = tuple(ctx.short_positions())\n",
    "    # Get long position for current ctx.symbol.\n",
    "    long_position = ctx.long_pos()\n",
    "    # Get short position for a symbol.\n",
    "    short_position = ctx.short_pos('QQQ')\n",
    "        \n",
    "strategy = Strategy(YFinance(), start_date='3/1/2022', end_date='1/1/2023')\n",
    "strategy.add_execution(exec_fn, ['SPY', 'QQQ'])\n",
    "result = strategy.backtest()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b8ba4083",
   "metadata": {},
   "source": [
    "[See the Position class for more information.](https://www.pybroker.com/en/latest/reference/pybroker.portfolio.html#pybroker.portfolio.Position)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc5b00aa",
   "metadata": {},
   "source": [
    "### ... use custom column data?\n",
    "\n",
    "Register your custom columns with [pybroker.register_columns](https://www.pybroker.com/en/latest/reference/pybroker.scope.html#pybroker.scope.register_columns):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "d49664bf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loading bar data...\n",
      "[*********************100%***********************]  1 of 1 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Backtesting: 2022-03-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Test split: 2022-03-01 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (212 of 212) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>symbol</th>\n",
       "      <th>date</th>\n",
       "      <th>shares</th>\n",
       "      <th>limit_price</th>\n",
       "      <th>fill_price</th>\n",
       "      <th>fees</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-02</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>435.65</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-03</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>437.45</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-04</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>430.62</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-07</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>425.83</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-08</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>421.16</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-09</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>426.17</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-10</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>423.43</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-11</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>424.15</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-14</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>420.17</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-15</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>422.63</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    type symbol       date  shares  limit_price  fill_price  fees\n",
       "id                                                               \n",
       "1    buy    SPY 2022-03-02     100          NaN      435.65   0.0\n",
       "2   sell    SPY 2022-03-03     100          NaN      437.45   0.0\n",
       "3    buy    SPY 2022-03-04     100          NaN      430.62   0.0\n",
       "4   sell    SPY 2022-03-07     100          NaN      425.83   0.0\n",
       "5    buy    SPY 2022-03-08     100          NaN      421.16   0.0\n",
       "6   sell    SPY 2022-03-09     100          NaN      426.17   0.0\n",
       "7    buy    SPY 2022-03-10     100          NaN      423.43   0.0\n",
       "8   sell    SPY 2022-03-11     100          NaN      424.15   0.0\n",
       "9    buy    SPY 2022-03-14     100          NaN      420.17   0.0\n",
       "10  sell    SPY 2022-03-15     100          NaN      422.63   0.0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pybroker\n",
    "from pybroker import ExecContext, Strategy, YFinance\n",
    "\n",
    "yf = YFinance()\n",
    "df = yf.query('SPY', start_date='1/1/2022', end_date='1/1/2023')\n",
    "df['buy_signal'] = 1\n",
    "\n",
    "def buy_fn(ctx: ExecContext):\n",
    "    if not ctx.long_pos() and ctx.buy_signal[-1] == 1:\n",
    "        ctx.buy_shares = 100\n",
    "        ctx.hold_bars = 1\n",
    "        \n",
    "pybroker.register_columns('buy_signal')\n",
    "strategy = Strategy(df, start_date='3/1/2022', end_date='1/1/2023')\n",
    "strategy.add_execution(buy_fn, 'SPY')\n",
    "result = strategy.backtest()\n",
    "result.orders.head(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "387f1842",
   "metadata": {},
   "source": [
    "### ... place an order more than one bar ahead?\n",
    "\n",
    "Use the [buy_delay](https://www.pybroker.com/en/latest/reference/pybroker.config.html#pybroker.config.StrategyConfig.buy_delay) and [sell_delay](https://www.pybroker.com/en/latest/reference/pybroker.config.html#pybroker.config.StrategyConfig.sell_delay) configuration options:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "39d5bcda",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-03-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  1 of 1 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2022-03-01 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (212 of 212) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>symbol</th>\n",
       "      <th>date</th>\n",
       "      <th>shares</th>\n",
       "      <th>limit_price</th>\n",
       "      <th>fill_price</th>\n",
       "      <th>fees</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-08</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>421.16</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-09</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>426.17</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-16</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>430.24</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-17</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>437.13</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-24</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>447.63</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-25</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>450.71</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-01</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>451.30</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-04</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>454.59</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-11</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>442.20</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-12</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>441.20</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    type symbol       date  shares  limit_price  fill_price  fees\n",
       "id                                                               \n",
       "1    buy    SPY 2022-03-08     100          NaN      421.16   0.0\n",
       "2   sell    SPY 2022-03-09     100          NaN      426.17   0.0\n",
       "3    buy    SPY 2022-03-16     100          NaN      430.24   0.0\n",
       "4   sell    SPY 2022-03-17     100          NaN      437.13   0.0\n",
       "5    buy    SPY 2022-03-24     100          NaN      447.63   0.0\n",
       "6   sell    SPY 2022-03-25     100          NaN      450.71   0.0\n",
       "7    buy    SPY 2022-04-01     100          NaN      451.30   0.0\n",
       "8   sell    SPY 2022-04-04     100          NaN      454.59   0.0\n",
       "9    buy    SPY 2022-04-11     100          NaN      442.20   0.0\n",
       "10  sell    SPY 2022-04-12     100          NaN      441.20   0.0"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pybroker import ExecContext, Strategy, StrategyConfig, YFinance\n",
    "\n",
    "def buy_fn(ctx: ExecContext):\n",
    "    if not tuple(ctx.pending_orders()) and not ctx.long_pos():\n",
    "        ctx.buy_shares = 100\n",
    "        ctx.hold_bars = 1\n",
    "\n",
    "config = StrategyConfig(buy_delay=5)\n",
    "strategy = Strategy(YFinance(), start_date='3/1/2022', end_date='1/1/2023', config=config)\n",
    "strategy.add_execution(buy_fn, 'SPY')\n",
    "result = strategy.backtest()\n",
    "result.orders.head(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f2225e38",
   "metadata": {},
   "source": [
    "### ... cancel pending orders?\n",
    "\n",
    "See the [cancel_pending_order](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext.cancel_pending_order) and [cancel_all_pending_orders](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext.cancel_all_pending_orders) methods."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "cdec0461",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-03-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  1 of 1 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2022-03-01 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (212 of 212) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>symbol</th>\n",
       "      <th>date</th>\n",
       "      <th>shares</th>\n",
       "      <th>limit_price</th>\n",
       "      <th>fill_price</th>\n",
       "      <th>fees</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-23</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>446.10</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-24</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>447.63</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-31</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>454.96</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-01</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>451.30</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-08</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>448.29</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-11</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>442.20</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-19</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>441.74</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-20</td>\n",
       "      <td>100</td>\n",
       "      <td>NaN</td>\n",
       "      <td>445.53</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    type symbol       date  shares  limit_price  fill_price  fees\n",
       "id                                                               \n",
       "1    buy    SPY 2022-03-23     100          NaN      446.10   0.0\n",
       "2   sell    SPY 2022-03-24     100          NaN      447.63   0.0\n",
       "3    buy    SPY 2022-03-31     100          NaN      454.96   0.0\n",
       "4   sell    SPY 2022-04-01     100          NaN      451.30   0.0\n",
       "5    buy    SPY 2022-04-08     100          NaN      448.29   0.0\n",
       "6   sell    SPY 2022-04-11     100          NaN      442.20   0.0\n",
       "7    buy    SPY 2022-04-19     100          NaN      441.74   0.0\n",
       "8   sell    SPY 2022-04-20     100          NaN      445.53   0.0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pybroker import ExecContext, Strategy, StrategyConfig, YFinance\n",
    "\n",
    "def buy_fn(ctx: ExecContext):\n",
    "    pending = tuple(ctx.pending_orders())\n",
    "    if not pending and not ctx.long_pos():\n",
    "        ctx.buy_shares = 100\n",
    "        ctx.hold_bars = 1\n",
    "    if pending and ctx.close[-1] < 430:\n",
    "        ctx.cancel_all_pending_orders(ctx.symbol)\n",
    "\n",
    "config = StrategyConfig(buy_delay=5)\n",
    "strategy = Strategy(YFinance(), start_date='3/1/2022', end_date='1/1/2023', config=config)\n",
    "strategy.add_execution(buy_fn, 'SPY')\n",
    "result = strategy.backtest()\n",
    "result.orders.head(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcbd18bb",
   "metadata": {},
   "source": [
    "### ... persist data across bars?\n",
    "\n",
    "Use the [ExecContext#session](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext.session) dictionary:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "05b832ce",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-01-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  1 of 1 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2022-01-03 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (251 of 251) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    }
   ],
   "source": [
    "from pybroker import ExecContext, Strategy, YFinance\n",
    "\n",
    "def buy_fn(ctx: ExecContext):\n",
    "    if not ctx.long_pos():\n",
    "        ctx.buy_shares = 100\n",
    "        ctx.hold_bars = 1\n",
    "        count = ctx.session.get('entry_count', 0)\n",
    "        ctx.session['entry_count'] = count + 1\n",
    "\n",
    "strategy = Strategy(YFinance(), start_date='1/1/2022', end_date='1/1/2023')\n",
    "strategy.add_execution(buy_fn, 'SPY')\n",
    "result = strategy.backtest()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f4362c62",
   "metadata": {},
   "source": [
    "### ... exit a position?\n",
    "\n",
    "Use [sell_all_shares()](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext.sell_all_shares) or [cover_all_shares()](https://www.pybroker.com/en/latest/reference/pybroker.context.html#pybroker.context.ExecContext.cover_all_shares) to liquidate a position:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b5ad457f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-01-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  1 of 1 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2022-01-03 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (251 of 251) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>symbol</th>\n",
       "      <th>entry_date</th>\n",
       "      <th>exit_date</th>\n",
       "      <th>entry</th>\n",
       "      <th>exit</th>\n",
       "      <th>shares</th>\n",
       "      <th>pnl</th>\n",
       "      <th>return_pct</th>\n",
       "      <th>agg_pnl</th>\n",
       "      <th>bars</th>\n",
       "      <th>pnl_per_bar</th>\n",
       "      <th>stop</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>long</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-01-04</td>\n",
       "      <td>2022-02-18</td>\n",
       "      <td>477.78</td>\n",
       "      <td>435.24</td>\n",
       "      <td>100</td>\n",
       "      <td>-4254.0</td>\n",
       "      <td>-8.90</td>\n",
       "      <td>-4254.0</td>\n",
       "      <td>32</td>\n",
       "      <td>-132.94</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>long</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-02-22</td>\n",
       "      <td>2022-04-07</td>\n",
       "      <td>430.68</td>\n",
       "      <td>447.11</td>\n",
       "      <td>100</td>\n",
       "      <td>1643.0</td>\n",
       "      <td>3.81</td>\n",
       "      <td>-2611.0</td>\n",
       "      <td>32</td>\n",
       "      <td>51.34</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>long</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-04-08</td>\n",
       "      <td>2022-05-25</td>\n",
       "      <td>448.29</td>\n",
       "      <td>395.67</td>\n",
       "      <td>100</td>\n",
       "      <td>-5262.0</td>\n",
       "      <td>-11.74</td>\n",
       "      <td>-7873.0</td>\n",
       "      <td>32</td>\n",
       "      <td>-164.44</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>long</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-05-26</td>\n",
       "      <td>2022-07-14</td>\n",
       "      <td>402.75</td>\n",
       "      <td>375.04</td>\n",
       "      <td>100</td>\n",
       "      <td>-2771.0</td>\n",
       "      <td>-6.88</td>\n",
       "      <td>-10644.0</td>\n",
       "      <td>32</td>\n",
       "      <td>-86.59</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>long</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-07-15</td>\n",
       "      <td>2022-08-30</td>\n",
       "      <td>382.90</td>\n",
       "      <td>400.05</td>\n",
       "      <td>100</td>\n",
       "      <td>1715.0</td>\n",
       "      <td>4.48</td>\n",
       "      <td>-8929.0</td>\n",
       "      <td>32</td>\n",
       "      <td>53.59</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>long</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-08-31</td>\n",
       "      <td>2022-10-17</td>\n",
       "      <td>398.14</td>\n",
       "      <td>362.63</td>\n",
       "      <td>100</td>\n",
       "      <td>-3551.0</td>\n",
       "      <td>-8.92</td>\n",
       "      <td>-12480.0</td>\n",
       "      <td>32</td>\n",
       "      <td>-110.97</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>long</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-10-18</td>\n",
       "      <td>2022-12-02</td>\n",
       "      <td>371.49</td>\n",
       "      <td>405.00</td>\n",
       "      <td>100</td>\n",
       "      <td>3351.0</td>\n",
       "      <td>9.02</td>\n",
       "      <td>-9129.0</td>\n",
       "      <td>32</td>\n",
       "      <td>104.72</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    type symbol entry_date  exit_date   entry    exit  shares     pnl  \\\n",
       "id                                                                      \n",
       "1   long    SPY 2022-01-04 2022-02-18  477.78  435.24     100 -4254.0   \n",
       "2   long    SPY 2022-02-22 2022-04-07  430.68  447.11     100  1643.0   \n",
       "3   long    SPY 2022-04-08 2022-05-25  448.29  395.67     100 -5262.0   \n",
       "4   long    SPY 2022-05-26 2022-07-14  402.75  375.04     100 -2771.0   \n",
       "5   long    SPY 2022-07-15 2022-08-30  382.90  400.05     100  1715.0   \n",
       "6   long    SPY 2022-08-31 2022-10-17  398.14  362.63     100 -3551.0   \n",
       "7   long    SPY 2022-10-18 2022-12-02  371.49  405.00     100  3351.0   \n",
       "\n",
       "    return_pct  agg_pnl  bars  pnl_per_bar  stop  \n",
       "id                                                \n",
       "1        -8.90  -4254.0    32      -132.94  None  \n",
       "2         3.81  -2611.0    32        51.34  None  \n",
       "3       -11.74  -7873.0    32      -164.44  None  \n",
       "4        -6.88 -10644.0    32       -86.59  None  \n",
       "5         4.48  -8929.0    32        53.59  None  \n",
       "6        -8.92 -12480.0    32      -110.97  None  \n",
       "7         9.02  -9129.0    32       104.72  None  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pybroker import ExecContext, Strategy, YFinance\n",
    "\n",
    "def buy_fn(ctx: ExecContext):\n",
    "    pos = ctx.long_pos()\n",
    "    if not pos:\n",
    "        ctx.buy_shares = 100\n",
    "    elif pos.bars > 30:\n",
    "        ctx.sell_all_shares()\n",
    "\n",
    "strategy = Strategy(YFinance(), start_date='1/1/2022', end_date='1/1/2023')\n",
    "strategy.add_execution(buy_fn, 'SPY')\n",
    "result = strategy.backtest()\n",
    "result.trades"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "95c96009",
   "metadata": {},
   "source": [
    "### ... process multiple symbols at once?\n",
    "\n",
    "Use [set_before_exec](https://www.pybroker.com/en/latest/reference/pybroker.strategy.html#pybroker.strategy.Strategy.set_before_exec) or [set_after_exec](https://www.pybroker.com/en/latest/reference/pybroker.strategy.html#pybroker.strategy.Strategy.set_after_exec):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "4ab5ac9d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-01-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  2 of 2 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2022-01-03 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (251 of 251) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>symbol</th>\n",
       "      <th>entry_date</th>\n",
       "      <th>exit_date</th>\n",
       "      <th>entry</th>\n",
       "      <th>exit</th>\n",
       "      <th>shares</th>\n",
       "      <th>pnl</th>\n",
       "      <th>return_pct</th>\n",
       "      <th>agg_pnl</th>\n",
       "      <th>bars</th>\n",
       "      <th>pnl_per_bar</th>\n",
       "      <th>stop</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>long</td>\n",
       "      <td>NVDA</td>\n",
       "      <td>2022-01-05</td>\n",
       "      <td>2022-01-10</td>\n",
       "      <td>284.74</td>\n",
       "      <td>265.57</td>\n",
       "      <td>100</td>\n",
       "      <td>-1917.0</td>\n",
       "      <td>-6.73</td>\n",
       "      <td>-1917.0</td>\n",
       "      <td>3</td>\n",
       "      <td>-639.00</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>short</td>\n",
       "      <td>AMD</td>\n",
       "      <td>2022-01-05</td>\n",
       "      <td>2022-01-10</td>\n",
       "      <td>139.52</td>\n",
       "      <td>128.72</td>\n",
       "      <td>100</td>\n",
       "      <td>1080.0</td>\n",
       "      <td>8.39</td>\n",
       "      <td>-837.0</td>\n",
       "      <td>3</td>\n",
       "      <td>360.00</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>long</td>\n",
       "      <td>NVDA</td>\n",
       "      <td>2022-01-14</td>\n",
       "      <td>2022-01-20</td>\n",
       "      <td>267.04</td>\n",
       "      <td>248.28</td>\n",
       "      <td>100</td>\n",
       "      <td>-1876.0</td>\n",
       "      <td>-7.03</td>\n",
       "      <td>-2713.0</td>\n",
       "      <td>3</td>\n",
       "      <td>-625.33</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>short</td>\n",
       "      <td>AMD</td>\n",
       "      <td>2022-01-14</td>\n",
       "      <td>2022-01-20</td>\n",
       "      <td>134.21</td>\n",
       "      <td>124.96</td>\n",
       "      <td>100</td>\n",
       "      <td>925.0</td>\n",
       "      <td>7.40</td>\n",
       "      <td>-1788.0</td>\n",
       "      <td>3</td>\n",
       "      <td>308.33</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>long</td>\n",
       "      <td>NVDA</td>\n",
       "      <td>2022-01-21</td>\n",
       "      <td>2022-01-26</td>\n",
       "      <td>240.43</td>\n",
       "      <td>231.79</td>\n",
       "      <td>100</td>\n",
       "      <td>-864.0</td>\n",
       "      <td>-3.59</td>\n",
       "      <td>-2652.0</td>\n",
       "      <td>3</td>\n",
       "      <td>-288.00</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>76</th>\n",
       "      <td>short</td>\n",
       "      <td>AMD</td>\n",
       "      <td>2022-12-07</td>\n",
       "      <td>2022-12-12</td>\n",
       "      <td>70.33</td>\n",
       "      <td>69.10</td>\n",
       "      <td>100</td>\n",
       "      <td>123.0</td>\n",
       "      <td>1.78</td>\n",
       "      <td>1863.0</td>\n",
       "      <td>3</td>\n",
       "      <td>41.00</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>77</th>\n",
       "      <td>long</td>\n",
       "      <td>NVDA</td>\n",
       "      <td>2022-12-15</td>\n",
       "      <td>2022-12-20</td>\n",
       "      <td>170.10</td>\n",
       "      <td>160.81</td>\n",
       "      <td>100</td>\n",
       "      <td>-929.0</td>\n",
       "      <td>-5.46</td>\n",
       "      <td>934.0</td>\n",
       "      <td>3</td>\n",
       "      <td>-309.67</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>78</th>\n",
       "      <td>short</td>\n",
       "      <td>AMD</td>\n",
       "      <td>2022-12-15</td>\n",
       "      <td>2022-12-20</td>\n",
       "      <td>67.17</td>\n",
       "      <td>64.79</td>\n",
       "      <td>100</td>\n",
       "      <td>238.0</td>\n",
       "      <td>3.67</td>\n",
       "      <td>1172.0</td>\n",
       "      <td>3</td>\n",
       "      <td>79.33</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>79</th>\n",
       "      <td>long</td>\n",
       "      <td>NVDA</td>\n",
       "      <td>2022-12-21</td>\n",
       "      <td>2022-12-27</td>\n",
       "      <td>163.65</td>\n",
       "      <td>145.78</td>\n",
       "      <td>100</td>\n",
       "      <td>-1787.0</td>\n",
       "      <td>-10.92</td>\n",
       "      <td>-615.0</td>\n",
       "      <td>3</td>\n",
       "      <td>-595.67</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>80</th>\n",
       "      <td>short</td>\n",
       "      <td>AMD</td>\n",
       "      <td>2022-12-21</td>\n",
       "      <td>2022-12-27</td>\n",
       "      <td>66.53</td>\n",
       "      <td>63.62</td>\n",
       "      <td>100</td>\n",
       "      <td>291.0</td>\n",
       "      <td>4.57</td>\n",
       "      <td>-324.0</td>\n",
       "      <td>3</td>\n",
       "      <td>97.00</td>\n",
       "      <td>bar</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>80 rows × 13 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "     type symbol entry_date  exit_date   entry    exit  shares     pnl  \\\n",
       "id                                                                       \n",
       "1    long   NVDA 2022-01-05 2022-01-10  284.74  265.57     100 -1917.0   \n",
       "2   short    AMD 2022-01-05 2022-01-10  139.52  128.72     100  1080.0   \n",
       "3    long   NVDA 2022-01-14 2022-01-20  267.04  248.28     100 -1876.0   \n",
       "4   short    AMD 2022-01-14 2022-01-20  134.21  124.96     100   925.0   \n",
       "5    long   NVDA 2022-01-21 2022-01-26  240.43  231.79     100  -864.0   \n",
       "..    ...    ...        ...        ...     ...     ...     ...     ...   \n",
       "76  short    AMD 2022-12-07 2022-12-12   70.33   69.10     100   123.0   \n",
       "77   long   NVDA 2022-12-15 2022-12-20  170.10  160.81     100  -929.0   \n",
       "78  short    AMD 2022-12-15 2022-12-20   67.17   64.79     100   238.0   \n",
       "79   long   NVDA 2022-12-21 2022-12-27  163.65  145.78     100 -1787.0   \n",
       "80  short    AMD 2022-12-21 2022-12-27   66.53   63.62     100   291.0   \n",
       "\n",
       "    return_pct  agg_pnl  bars  pnl_per_bar stop  \n",
       "id                                               \n",
       "1        -6.73  -1917.0     3      -639.00  bar  \n",
       "2         8.39   -837.0     3       360.00  bar  \n",
       "3        -7.03  -2713.0     3      -625.33  bar  \n",
       "4         7.40  -1788.0     3       308.33  bar  \n",
       "5        -3.59  -2652.0     3      -288.00  bar  \n",
       "..         ...      ...   ...          ...  ...  \n",
       "76        1.78   1863.0     3        41.00  bar  \n",
       "77       -5.46    934.0     3      -309.67  bar  \n",
       "78        3.67   1172.0     3        79.33  bar  \n",
       "79      -10.92   -615.0     3      -595.67  bar  \n",
       "80        4.57   -324.0     3        97.00  bar  \n",
       "\n",
       "[80 rows x 13 columns]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pybroker import ExecContext, Strategy, YFinance\n",
    "\n",
    "def long_short_fn(ctxs: dict[str, ExecContext]):\n",
    "    nvda_ctx = ctxs['NVDA']\n",
    "    amd_ctx = ctxs['AMD']\n",
    "    if nvda_ctx.long_pos() or amd_ctx.short_pos():\n",
    "        return\n",
    "    if nvda_ctx.bars >= 2 and nvda_ctx.close[-1] < nvda_ctx.low[-2]:\n",
    "        nvda_ctx.buy_shares = 100\n",
    "        nvda_ctx.hold_bars = 3\n",
    "        amd_ctx.sell_shares = 100\n",
    "        amd_ctx.hold_bars = 3\n",
    "\n",
    "strategy = Strategy(YFinance(), start_date='1/1/2022', end_date='1/1/2023')\n",
    "strategy.add_execution(None, ['NVDA', 'AMD'])\n",
    "strategy.set_after_exec(long_short_fn)\n",
    "result = strategy.backtest()\n",
    "result.trades"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3dde213c",
   "metadata": {},
   "source": [
    "### ... annualize the Sharpe Ratio?\n",
    "\n",
    "Set the [bars_per_year](https://www.pybroker.com/en/latest/reference/pybroker.config.html#pybroker.config.StrategyConfig.bars_per_year) configuration option. For example, setting a value of ``252`` would be used to annualize daily returns."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "60872f0e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-01-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  1 of 1 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2022-01-03 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (251 of 251) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "-0.8930247224724036"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pybroker import ExecContext, Strategy, StrategyConfig, YFinance\n",
    "\n",
    "def buy_fn(ctx: ExecContext):\n",
    "    if ctx.long_pos() or ctx.bars < 2:\n",
    "        return\n",
    "    if ctx.close[-1] < ctx.high[-2]:\n",
    "        ctx.buy_shares = 100\n",
    "        ctx.hold_bars = 1\n",
    "\n",
    "config = StrategyConfig(bars_per_year=252)\n",
    "strategy = Strategy(YFinance(), start_date='1/1/2022', end_date='1/1/2023', config=config)\n",
    "strategy.add_execution(buy_fn, 'SPY')\n",
    "result = strategy.backtest()\n",
    "result.metrics.sharpe"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7607beb6",
   "metadata": {},
   "source": [
    "### ... limit margin used for short selling?\n",
    "\n",
    "By default, PyBroker does not limit the amount of margin that can be used for short selling. However, you can manually limit the amount of margin that can be used:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "82b93739",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-01-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  2 of 2 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2022-01-03 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (251 of 251) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cash</th>\n",
       "      <th>equity</th>\n",
       "      <th>margin</th>\n",
       "      <th>market_value</th>\n",
       "      <th>pnl</th>\n",
       "      <th>unrealized_pnl</th>\n",
       "      <th>fees</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2022-01-03</th>\n",
       "      <td>100000.00</td>\n",
       "      <td>100000.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>100000.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-01-04</th>\n",
       "      <td>100000.00</td>\n",
       "      <td>100000.00</td>\n",
       "      <td>289702.46</td>\n",
       "      <td>102722.18</td>\n",
       "      <td>0.00</td>\n",
       "      <td>2722.18</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-01-05</th>\n",
       "      <td>111667.90</td>\n",
       "      <td>111667.90</td>\n",
       "      <td>0.00</td>\n",
       "      <td>111667.90</td>\n",
       "      <td>11667.90</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-01-06</th>\n",
       "      <td>111667.90</td>\n",
       "      <td>111667.90</td>\n",
       "      <td>338321.57</td>\n",
       "      <td>107432.09</td>\n",
       "      <td>11667.90</td>\n",
       "      <td>-4235.81</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-01-07</th>\n",
       "      <td>112472.56</td>\n",
       "      <td>112472.56</td>\n",
       "      <td>0.00</td>\n",
       "      <td>112472.56</td>\n",
       "      <td>12472.56</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-01-10</th>\n",
       "      <td>112472.56</td>\n",
       "      <td>112472.56</td>\n",
       "      <td>338302.00</td>\n",
       "      <td>103062.55</td>\n",
       "      <td>12472.56</td>\n",
       "      <td>-9410.01</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-01-11</th>\n",
       "      <td>98536.05</td>\n",
       "      <td>98536.05</td>\n",
       "      <td>0.00</td>\n",
       "      <td>98536.05</td>\n",
       "      <td>-1463.95</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-01-12</th>\n",
       "      <td>98536.05</td>\n",
       "      <td>98536.05</td>\n",
       "      <td>296592.41</td>\n",
       "      <td>99830.87</td>\n",
       "      <td>-1463.95</td>\n",
       "      <td>1294.82</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-01-13</th>\n",
       "      <td>103550.41</td>\n",
       "      <td>103550.41</td>\n",
       "      <td>0.00</td>\n",
       "      <td>103550.41</td>\n",
       "      <td>3550.41</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022-01-14</th>\n",
       "      <td>103550.41</td>\n",
       "      <td>103550.41</td>\n",
       "      <td>317490.89</td>\n",
       "      <td>99036.58</td>\n",
       "      <td>3550.41</td>\n",
       "      <td>-4513.83</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 cash     equity     margin  market_value       pnl  \\\n",
       "date                                                                  \n",
       "2022-01-03  100000.00  100000.00       0.00     100000.00      0.00   \n",
       "2022-01-04  100000.00  100000.00  289702.46     102722.18      0.00   \n",
       "2022-01-05  111667.90  111667.90       0.00     111667.90  11667.90   \n",
       "2022-01-06  111667.90  111667.90  338321.57     107432.09  11667.90   \n",
       "2022-01-07  112472.56  112472.56       0.00     112472.56  12472.56   \n",
       "2022-01-10  112472.56  112472.56  338302.00     103062.55  12472.56   \n",
       "2022-01-11   98536.05   98536.05       0.00      98536.05  -1463.95   \n",
       "2022-01-12   98536.05   98536.05  296592.41      99830.87  -1463.95   \n",
       "2022-01-13  103550.41  103550.41       0.00     103550.41   3550.41   \n",
       "2022-01-14  103550.41  103550.41  317490.89      99036.58   3550.41   \n",
       "\n",
       "            unrealized_pnl  fees  \n",
       "date                              \n",
       "2022-01-03            0.00   0.0  \n",
       "2022-01-04         2722.18   0.0  \n",
       "2022-01-05            0.00   0.0  \n",
       "2022-01-06        -4235.81   0.0  \n",
       "2022-01-07            0.00   0.0  \n",
       "2022-01-10        -9410.01   0.0  \n",
       "2022-01-11            0.00   0.0  \n",
       "2022-01-12         1294.82   0.0  \n",
       "2022-01-13            0.00   0.0  \n",
       "2022-01-14        -4513.83   0.0  "
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pybroker\n",
    "from pybroker import ExecContext\n",
    "from decimal import Decimal\n",
    "\n",
    "def short_fn(ctx: ExecContext):\n",
    "    margin_requirement = Decimal('0.25')\n",
    "    max_margin = ctx.total_equity / margin_requirement - ctx.total_equity\n",
    "    if not ctx.short_pos():\n",
    "        available_margin = max_margin - ctx.total_margin\n",
    "        ctx.sell_shares = ctx.calc_target_shares(0.5, cash=available_margin)\n",
    "        ctx.hold_bars = 1\n",
    "        \n",
    "strategy = Strategy(YFinance(), start_date='1/1/2022', end_date='1/1/2023')\n",
    "strategy.add_execution(short_fn, ['NVDA', 'AMD'])\n",
    "result = strategy.backtest()\n",
    "result.portfolio.head(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3afacc1",
   "metadata": {},
   "source": [
    "### ... get and set a global parameter?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "11c8a5af",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "100"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pybroker\n",
    "\n",
    "# Set parameter.\n",
    "pybroker.param('lookback', 100)\n",
    "\n",
    "# Get parameter.\n",
    "pybroker.param('lookback')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "06631bd5",
   "metadata": {},
   "source": [
    "### ... apply random slippage?\n",
    "\n",
    "Set a [RandomSlippageModel](https://www.pybroker.com/en/latest/reference/pybroker.slippage.html#pybroker.slippage.RandomSlippageModel):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "615e147e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtesting: 2022-03-01 00:00:00 to 2023-01-01 00:00:00\n",
      "\n",
      "Loading bar data...\n",
      "[*********************100%***********************]  1 of 1 completed\n",
      "Loaded bar data: 0:00:00 \n",
      "\n",
      "Test split: 2022-03-01 00:00:00 to 2022-12-30 00:00:00\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100% (212 of 212) |######################| Elapsed Time: 0:00:00 Time:  0:00:00\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Finished backtest: 0:00:00\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>symbol</th>\n",
       "      <th>date</th>\n",
       "      <th>shares</th>\n",
       "      <th>limit_price</th>\n",
       "      <th>fill_price</th>\n",
       "      <th>fees</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-02</td>\n",
       "      <td>98</td>\n",
       "      <td>NaN</td>\n",
       "      <td>435.65</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-03</td>\n",
       "      <td>98</td>\n",
       "      <td>NaN</td>\n",
       "      <td>437.45</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-04</td>\n",
       "      <td>98</td>\n",
       "      <td>NaN</td>\n",
       "      <td>430.62</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-07</td>\n",
       "      <td>98</td>\n",
       "      <td>NaN</td>\n",
       "      <td>425.83</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-08</td>\n",
       "      <td>98</td>\n",
       "      <td>NaN</td>\n",
       "      <td>421.16</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-09</td>\n",
       "      <td>98</td>\n",
       "      <td>NaN</td>\n",
       "      <td>426.17</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-10</td>\n",
       "      <td>97</td>\n",
       "      <td>NaN</td>\n",
       "      <td>423.43</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-11</td>\n",
       "      <td>97</td>\n",
       "      <td>NaN</td>\n",
       "      <td>424.15</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>buy</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-14</td>\n",
       "      <td>97</td>\n",
       "      <td>NaN</td>\n",
       "      <td>420.17</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>sell</td>\n",
       "      <td>SPY</td>\n",
       "      <td>2022-03-15</td>\n",
       "      <td>97</td>\n",
       "      <td>NaN</td>\n",
       "      <td>422.63</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    type symbol       date  shares  limit_price  fill_price  fees\n",
       "id                                                               \n",
       "1    buy    SPY 2022-03-02      98          NaN      435.65   0.0\n",
       "2   sell    SPY 2022-03-03      98          NaN      437.45   0.0\n",
       "3    buy    SPY 2022-03-04      98          NaN      430.62   0.0\n",
       "4   sell    SPY 2022-03-07      98          NaN      425.83   0.0\n",
       "5    buy    SPY 2022-03-08      98          NaN      421.16   0.0\n",
       "6   sell    SPY 2022-03-09      98          NaN      426.17   0.0\n",
       "7    buy    SPY 2022-03-10      97          NaN      423.43   0.0\n",
       "8   sell    SPY 2022-03-11      97          NaN      424.15   0.0\n",
       "9    buy    SPY 2022-03-14      97          NaN      420.17   0.0\n",
       "10  sell    SPY 2022-03-15      97          NaN      422.63   0.0"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pybroker import ExecContext, RandomSlippageModel, Strategy, YFinance\n",
    "\n",
    "def buy_fn(ctx: ExecContext):\n",
    "    if not ctx.long_pos():\n",
    "        ctx.buy_shares = 100\n",
    "        ctx.hold_bars = 1\n",
    "\n",
    "slippage = RandomSlippageModel(min_pct=1.0, max_pct=5.0) # Slippage of 1-5%\n",
    "strategy = Strategy(YFinance(), start_date='3/1/2022', end_date='1/1/2023')\n",
    "strategy.set_slippage_model(slippage)\n",
    "strategy.add_execution(buy_fn, 'SPY')\n",
    "result = strategy.backtest()\n",
    "result.orders.head(10)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
